# -*- coding: utf-8 -*-
import csv
import base64
import hashlib
from datetime import datetime, timedelta, date

from django import forms
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.utils.http import mark_for_escaping

from google.appengine.ext.db import djangoforms
from google.appengine.ext import db
from google.appengine.api import memcache

from finance.models import Transaction, RECORD_TYPE, LOCATION_TYPE, MonthTransaction, MonthTransactionManager
from finance.util.decorators import login_required, render_to, admin_required
from finance.util import paginate, get_date
from finance.util.iuc import _kr

import logging

class TransactionForm(djangoforms.ModelForm):
    class Meta:
        model = Transaction
        exclude = ('id',)

#    def clean(self):
#        cleaned_data = self.cleaned_data
#        school = cleaned_data['school']
#        if not school:
#            raise forms.ValidationError(u'학교명을 선택해야 합니다.')
#        year = cleaned_data['year']
#        month = cleaned_data['month']
#        type = cleaned_data['type']
#        temp_invoice = TempInvoiceManager.is_exist(school, year, month, type)
#        if not self.instance and temp_invoice:
#            raise forms.ValidationError(u'같은 invoice가 이미 존재합니다.')
#        if self.instance:
#            if (self.instance.school != school or
#                self.instance.year != year or
#                self.instance.month != month or
#                self.instance.type != type) and\
#                temp_invoice:
#                raise forms.ValidationError(u'같은 invoice가 이미 존재합니다.')
#        return cleaned_data


@admin_required
@render_to('transaction/form.html')
def create(request):
    form = TransactionForm()
    if request.method == 'POST':
        form = TransactionForm(request.POST)
        if form.is_valid():
            transaction = form.save(False)
            if transaction.type == RECORD_TYPE[0]:
                transaction.balance -= transaction.amount
            else:
                transaction.balance += transaction.amount
            transaction.put()
            return transaction.get_absolute_url
    return {
            'form': form,
            }

@admin_required
@render_to('transaction/detail.html')
def detail(request, transaction_id):
    transaction = Transaction.get_using_id(int(transaction_id))
    return {'transaction': transaction,}

@admin_required
@render_to('transaction/form.html')
def change(request, transaction_id):
    transaction = Transaction.get_using_id(int(transaction_id))
    form = TransactionForm(request.POST or None, instance=transaction)
    if form.is_valid():
        transaction = form.save()
        return transaction.get_absolute_url
    return {'form': form}

@admin_required
@render_to('transaction/list.html')
def delete(request, transaction_id):
    transaction = Transaction.get_using_id(int(transaction_id))
    transaction.delete()
    return HttpResponseRedirect(reverse('finance.views.transaction.list', args=()))

@admin_required
@render_to('transaction/list.html')
def year_list(request, year):

    year_m = {}
    for m in xrange(1, 13):
        year_m[m] = MonthTransactionManager.get_month(int(year), m)
    logging.info(year_m)
    return {
            'year': year,
            'year_m': year_m,
            }

@admin_required
@render_to('transaction/month_list.html')
def month_list(request, year, month):
    m = MonthTransactionManager.get_month(int(year), int(month))
    start_date = date(int(year), int(month), 1)
    end_date = get_date(start_date, 0, 1)
    query = Transaction.all().order('date').filter('date >=', start_date).filter('date <', end_date)
    paginator = paginate(request, query)

    expense, a_expense, k_expense = 0, 0, 0
    deposit, a_deposit, k_deposit = 0, 0, 0
    balance = 0

    for e in paginator.get('entities', []):
        if e.type == RECORD_TYPE[0]:
            expense += e.amount
            if e.location == LOCATION_TYPE[0]:
                a_expense += e.amount
            else:
                k_expense += e.amount
        else:
            deposit += e.amount
            if e.location == LOCATION_TYPE[1]:
                a_deposit += e.amount
            else:
                k_deposit += e.amount
        balance += e.balance

    m.expense = expense
    m.a_expense = a_expense
    m.k_expense = k_expense
    m.deposit = deposit
    m.a_deposit = a_deposit
    m.k_deposit = k_deposit
    m.balance = balance
    m.put()

    return {
            'year': year,
            'month': month,
            'paginator': paginator,
            'm': m,
            }

@admin_required
def month_csv(request, year, month):
    start_date = date(int(year), int(month), 1)
    end_date = get_date(start_date, 0, 1)
    query = Transaction.all().order('date').filter('date >=', start_date).filter('date <', end_date)
    transactions = query.fetch(1000)

    fname = year + '_' + month +'_transaction.csv'
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=' + fname

    writer = csv.writer(response)
    for t in transactions:

        writer.writerow([
                         t.date.strftime('%d %B %Y'),
                         t.category,
                         _kr(mark_for_escaping(t.detail)),
                         t.type,
                         t.amount,
                         t.balance,
                         _kr(mark_for_escaping(t.note)),
                         t.account,
                         t.location,
                         t.last_updated.strftime('%d %B %Y'),
                         ])
    return response
